圖片來源:梗圖倉庫
已購買,老八愛吃。
本篇藉前篇之小桃元素產生之問題,紀錄有發泡現象之focusin
與focusout
事件之事件委任應用。
委任一詞於法律之意,即謂當事人約定,一方委託他方處理事務,他方允為處理之契約。而用之於不可思議事件,即委託其他元素監聽事件之發生,並代為處理事件發生後之函式之術。而受委託之其他元素,通常為委託元素之父元素。
以下示例藉前篇之示例改造,以解決新生之小桃毫無反應之問題。
結構如下:
<div class="container">
<a class="momo" href="##"></a>
<a class="momo" href="##"></a>
<a class="momo" href="##"></a>
</div>
操術法如下:
const container = document.querySelector(".container");
function becomeEvil() {
this.style.backgroundImage = `url("./momo_ya.png")`;
}
function mitte() {
this.style.backgroundImage = `url("./momo_mitte.png")`;
}
function addMomo() {
const newMomo = document.createElement("a");
newMomo.setAttribute("class", "momo");
newMomo.setAttribute("href", "##");
container.insertBefore(newMomo, container.lastChild);
}
window.addEventListener("scrollend", addMomo);
container.addEventListener("focus", becomeEvil);
container.addEventListener("blur", mitte);
改造之處註釋如下:
僅選取小桃元素之父元素——容器元素。
const container = document.querySelector(".container");
對於容器元素設定二觀測器,觀測可發生發泡現象之focusin
與focusout
事件。
container.addEventListener("focusin", becomeEvil);
container.addEventListener("focusout", mitte);
利用focusin
與focusout
事件之發泡現象,可順利在小桃元素(子元素)受矚時向上至容器元素(父元素)觸發事件。
然而展露邪惡面向的元素並非小桃元素,而是容器元素,因此需要更改函式之術式內容:
function becomeEvil(event) {
event.target.style.backgroundImage = `url("./momo_ya.png")`;
}
function mitte(event) {
event.target.style.backgroundImage = `url("./momo_mitte.png")`;
}
將this
更改為事件之target
屬性,即可取得真正觸發事件之元素(示例即為小桃元素)。
MDN:
The read-only target property of the Event interface is a reference to the object onto which the event was dispatched.
故將函式之術改為更改event.target
之樣式,則可成功使新生之小桃元素顯露邪惡行為。
https://github.com/CReticulata/2024ithome/tree/main/Day20
事件委任:event delegation
受矚:focus